<?php

class SqlBuilder {
/* This Class buillds up SQL statments */

		public $Tables 		= 			array();
		public $Wheres 		= 			array();
		public $Fields 		= 			array();
		public $Orders 		= 			array();

		private $TableStruc;
		private $FieldStruc;
		private $OrderByStruc;
		private $WhereStruc;

		public $DB_PLATFORM;

	function __construct() {
		$this->FieldStruc		=			array('Name' =>'','Value' =>'');
		$this->TableStruc		=			array('Name'=>'','NameAlias'=>'');
		$this->OrderByStruc		=			array('Field'=>'','Ascending' =>'');
		$this->WhereStruc 		= 			array('Field'=>'', 'Operand'=>'','Value'=>'');
	}
	
	//allows you to add a table to select from and a table alias
	public function Table0($strTable){
		$strAlias = "";
		$this->AddRawTable($strTable,$strAlias);
	}
	
	public function Table1($strTable, $strAlias){
		$this->AddRawTable($strTable,$strAlias);
	}
	
	public function View($strView){
		$this->AddRawTable($strView);
	}
	
	private function AddRawTable($strTable, $strAlias){
		$oTable = $this->TableStruc;
		$oTable["Name"] = '`'.$strTable .'`';
		if ($strAlias != ''){
			$oTable["NameAlias"] = '`' . $strAlias . '`';
		}
		array_push($this->Tables, $oTable);
	}
	
	//Alows you add multiple where statements to the SQL 
	public function Where($field,$operand, $value){
		$this->AddRawWhere($field,$operand, $value);
	}
		
	private function AddRawWhere($field, $operand, $value){
		$oWhere = $this->WhereStruc;
		$oWhere["Field"] = $field;
		$oWhere["Value"] = $value;
		$oWhere["Operand"] = $operand;
		array_push($this->Wheres, $oWhere);
	}	

	// Field function so that there can be mutiple versions of this function one with 1 arg and 1 with 2 args
    public function __call($method, $arguments) {
		try{
			if($method == 'Field') {
				if(count($arguments) == 1) {
					return call_user_func_array(array($this,'Field0'), $arguments);
				}
				else if(count($arguments) == 2) {
					return call_user_func_array(array($this,'Field1'), $arguments);
			  }
			}
			if ($method =='Table'){
				if(count($arguments) == 1) {
					return call_user_func_array(array($this,'Table0'), $arguments);
				}
				else if(count($arguments) == 2) {
					return call_user_func_array(array($this,'Table1'), $arguments);
				}
			}
		} catch (Exception $e) {
			$this->Logger->Log(LogType::Error,$e->getMessage());
		}
   } 

	public function Field0($field) {
		$value = 0;
		$this->AddRawField($field,$value);
    }

    public function Field1($field, $Value) {
		$this->AddRawField($field,$Value);
    }
	
	private function AddRawField($field,$Value){
		$oField = $this->FieldStruc;
		$oField["Name"] = $field;
		$oField["Value"] = $Value;
		array_push($this->Fields, $oField);

	}
	
	public function OrderBy($Field, $Ascending){
		$this->AddRawOrderBy($Field, $Ascending);
	}
	
	private function AddRawOrderBy($Field,$Ascending){
		$oOrderBy = $OrderByStruc;
		$oOrderBy["Field"] = $Field;
		$oOrderBy["Ascending"] = $Ascending;
		array_push($this->Orders,$oOrderBy);
	}
	
	public function INSERTStatement(){
		try{
			$tempString = '';
			if (count($this->Tables) <> 1){
				throw new Exception('one table required');
			}
			$tempString = "INSERT INTO " . $this->Tables[0]["Name"];
			if (count($this->Fields) > 0){
				$tempString .="(";
				for($intIndex = 0; $intIndex  < sizeof($this->Fields);$intIndex++){
					$tempString .= $this->Fields[$intIndex]["Name"];
					if ($intIndex <> (sizeof($this->Fields)-1)){
						$tempString .=",";
					}
				}
				$tempString .= ") VALUES (";
				for($intIndex = 0;$intIndex  < sizeof($this->Fields);$intIndex++){
					switch($this->DB_PLATFORM){
						case DatabaseType::MySQL:
							$tempString .= "'".$this->Fields[$intIndex]["Value"]."'";
						break;
						case DatabaseType::Oracle:
							$tempString .= "\"".$this->Fields[$intIndex]["Value"]."\"";
						break;
						default:
							throw new Exception('Database Platform not defined');
						break;
					}
					if ($intIndex <> (count($this->Fields)-1)){
						$tempString .=",";
					}
				}
				$tempString .=")";
			}
			$this->ClearData();
			return $tempString;
		} catch (Exception $e) {
			$this->Logger->Log(LogType::Error,$e->getMessage());
		}
	}
	
	public function SELECTDISTINCTStatement(){
	
		return $this->BuildSelectStatemant(true);
	}
	
	public function SELECTStatement(){
		//echo("SELECT");
		$temp = $this->BuildSelectStatemant('false');
		//echo($temp);
		return $temp;
	}
	
	private function BuildSelectStatemant($bDistinct){
		try{
			$tempString = '';
			$tempString = 'SELECT ';
			if ($bDistinct == 'true'){
				$tempString .='DISTINCT ';
			}
			if (count($this->Fields) == 0){
				$tempString .= '*';
			}else{
				for($intIndex = 0;$intIndex  < sizeof($this->Fields);$intIndex++){
					$tempString .= $this->Fields[$intIndex]["Name"];
						if ($intIndex <> (sizeof($this->Fields)-1)){
							$tempString .=",";
						}
				}
			}
			if (count($this->Tables) <> 0){
				$tempString.=' FROM';
				for($intIndex = 0;$intIndex  < sizeof($this->Tables);$intIndex++){
					$tempString .= " ".  $this->Tables[$intIndex]["Name"] ." ";
						if ($intIndex <> (sizeof($this->Tables)-1)){
							$tempString .=",";
						}
				}
			}
			if (count($this->Wheres)<> 0){
				$tempString .=" WHERE ";
				for($intIndex = 0;$intIndex  < sizeof($this->Wheres);$intIndex++){
				$tempString .=" ". $this->Wheres[$intIndex]["Field"] . " " . $this->Wheres[$intIndex]["Operand"] ." '". $this->Wheres[$intIndex]["Value"]."'";
					if ($intIndex <> (sizeof($this->Wheres)-1)){
							$tempString .=" AND ";
						}
				}
			}
			if (count($this->Orders)<> 0)
			{
			$tempString .= " Order By ";
				for ($intIndex = 0; $intIndex < sizeof($this->Orders);$intIndex ++){
					$tempString .= $this->Orders[$intIndex]["Field"];
					if ($this->Orders[$intIndex]["Ascending"] == 'true'){
						$tempString .= ' ASC';
					}else{
						$tempString .= ' DESC';
					}
				}
			}
			$this->ClearData();
			return $tempString;
		} catch (Exception $e) {
			$this->Logger->Log(LogType::Error,$e->getMessage());
		}
	}

	public function UPDATEStatement(){
		try{
			$tempString = '';
			if (count($this->Tables) <> 1){
				throw new Exception('one table required');
			}
			$tempString = "UPDATE " . $this->Tables[0]["Name"] . " SET ";
			if (count($this->Fields) > 0){
				for($intIndex = 0; $intIndex  < sizeof($this->Fields);$intIndex++){
					$tempString .= $this->Fields[$intIndex]["Name"] . " = " . $this->Fields[$intIndex]["Value"];
					if ($intIndex <> (sizeof($this->Fields)-1)){
						$tempString .=", ";
					}
				}
				if (count($this->Wheres) <> 0){
					$tempString .=" WHERE ";
					for($intIndex = 0; $intIndex < sizeof($this->Wheres); $intIndex++){
						$tempString .=" ". $this->Wheres[$intIndex]["Field"] . " " . $this->Wheres[$intIndex]["Operand"] ." ". $this->Wheres[$intIndex]["Value"];
						if ($intIndex <> (sizeof($this->Wheres)-1)){
							$tempString .=" AND ";
						}
					}
				}
				$this->ClearData();
				return $tempString;
			}
		} catch (Exception $e) {
			$this->Logger->Log(LogType::Error,$e->getMessage());
		}

	}
	
	public function DROPTable(){
		try{
			$tempString = '';
			if (count($this->Tables) <> 1){
				throw new Exception('one table required');
			}
			$tempString = "DROP TABLE" . $this->Tables[0]["Name"];
			$this->ClearData();
			return $tempString;
		} catch (Exception $e) {
			$this->Logger->Log($e->getMessage());
		}
	}
	
	private function ClearData(){
		try{
			unset($this->Tables);
			unset($this->Wheres);
			unset($this->Fields);
			unset($this->Orders);
			$this->Tables 		= 			array();
			$this->Wheres 		= 			array();
			$this->Fields 		= 			array();
			$this->Orders 		= 			array();
		} catch (Exception $e) {
			$this->Logger->Log(LogType::Error,$e->getMessage());
		}
	}

}

?>
